package com.im.project.webSocket;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.im.common.constant.Constant;
import com.im.common.util.SpringContextHolder;
import com.im.common.util.StringTool;
import com.im.project.entity.User;
import com.im.project.mapper.UserMapper;
import com.im.project.service.impl.UserServiceImpl;
import io.netty.channel.Channel;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

/**
 * 用户和通道关系
 *
 * @author yunZhouJiaDi
 */
@Slf4j
public class UserChannelCtxMap {

    public static final ConcurrentMap<String, Channel> USER_CHANNEL_MAP = new ConcurrentHashMap(1024);

    public static void addContext(String userId, Channel channel) {
        String channelId = channel.id().toString();
        log.info("channelId:{}", channelId);
        AttributeKey attributeKey = null;
        if (!AttributeKey.exists(channelId)) {
            attributeKey = AttributeKey.newInstance(channel.id().toString());
        } else {
            attributeKey = AttributeKey.valueOf(channel.id().toString());
        }
        channel.attr(attributeKey).set(userId);
        USER_CHANNEL_MAP.put(userId, channel);
        RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");
        redisTemplate.opsForValue().set(Constant.RedisConstant.USER_HEART_BEAT + userId, System.currentTimeMillis(), 6L, TimeUnit.SECONDS);
        UserServiceImpl userServiceImpl = SpringContextHolder.getBean("userServiceImpl");
        userServiceImpl.pullMessage(userId);
    }

    public static Channel getContext(String userId) {
        if (userId != null && USER_CHANNEL_MAP.containsKey(userId)) {
            return USER_CHANNEL_MAP.get(userId);
        } else {
            return null;
        }
    }

    public static void removeContext(Channel channel) {
        Attribute<String> attribute = channel.attr(AttributeKey.valueOf(channel.id().toString()));
        String userId = attribute.get();
        if (!StringTool.isEmpty(userId)) {
            USER_CHANNEL_MAP.remove(userId);
        }
        RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");
        redisTemplate.delete(Constant.RedisConstant.USER_HEART_BEAT + userId);
        UserMapper userMapper = SpringContextHolder.getBean("userMapper");
        userMapper.update(
                new User().setLastOffTime(System.currentTimeMillis()),
                new QueryWrapper<User>().eq("user_id", userId)
        );
    }

    public static void closeContext(String userId) {
        if (StringTool.isEmpty(userId)) {
            return;
        }
        Channel channel = USER_CHANNEL_MAP.get(userId);
        USER_CHANNEL_MAP.remove(userId);
        if (channel != null) {
            channel.close();
        }
    }

}
